From 790b41b6b9871b7ff8705100d38fe0deee013ffd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 27 May 2025 11:39:10 +0200 Subject: [PATCH] pex: indicate refused update requests This is used, in case an unknown peer requests a network update. That way the peer can know that it is not considered to be a part of the network by the remote peer. Signed-off-by: Felix Fietkau --- network.h | 1 + pex-msg.c | 7 ++++++- pex-msg.h | 1 + pex.c | 19 +++++++++++++++++-- ubus.c | 5 +++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/network.h b/network.h index aa45b6b..57450cc 100644 --- a/network.h +++ b/network.h @@ -57,6 +57,7 @@ struct network { size_t net_data_len; uint64_t net_data_version; int num_net_queries; + unsigned int update_refused; struct uloop_timeout reload_timer; diff --git a/pex-msg.c b/pex-msg.c index fef5505..34b3bb9 100644 --- a/pex-msg.c +++ b/pex-msg.c @@ -480,6 +480,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op uint8_t enc_key[CURVE25519_KEY_SIZE]; void *ret; + if (timestamp) + *timestamp = 0; *data_len = 0; if (op == PEX_MSG_UPDATE_RESPONSE) { const struct pex_update_response *res = data; @@ -510,7 +512,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op data += sizeof(*res); len -= sizeof(*res); - } else if (op == PEX_MSG_UPDATE_RESPONSE_NO_DATA) { + } else if (op == PEX_MSG_UPDATE_RESPONSE_NO_DATA || + op == PEX_MSG_UPDATE_RESPONSE_REFUSED) { const struct pex_update_response_no_data *res = data; if (len < sizeof(*res) || !res->cur_version) @@ -520,6 +523,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op if (!ctx) return NULL; + if (timestamp) + *timestamp = be64_to_cpu(res->cur_version); goto error; } else { return NULL; diff --git a/pex-msg.h b/pex-msg.h index 36aade2..473d7ed 100644 --- a/pex-msg.h +++ b/pex-msg.h @@ -26,6 +26,7 @@ enum pex_opcode { PEX_MSG_ENDPOINT_NOTIFY, PEX_MSG_ENDPOINT_PORT_NOTIFY, PEX_MSG_ENROLL, + PEX_MSG_UPDATE_RESPONSE_REFUSED, }; #define PEX_ID_LEN 8 diff --git a/pex.c b/pex.c index cfd238f..a1c602d 100644 --- a/pex.c +++ b/pex.c @@ -572,7 +572,7 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer, D("receive update request, local version=%"PRIu64", remote version=%"PRIu64, net->net_data_version, req_version); - if (req_version && req_version >= net->net_data_version) { + if (peer && req_version && req_version >= net->net_data_version) { struct pex_update_response_no_data *res; pex_msg_init_ext(net, PEX_MSG_UPDATE_RESPONSE_NO_DATA, !!addr); @@ -584,6 +584,15 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer, if (req_version > net->net_data_version) network_pex_send_update_request(net, peer, addr); + else if (!peer && net->net_data_len) { + struct pex_update_response_no_data *res; + + pex_msg_init_ext(net, PEX_MSG_UPDATE_RESPONSE_REFUSED, !!addr); + res = pex_msg_append(sizeof(*res)); + res->req_id = req->req_id; + res->cur_version = cpu_to_be64(net->net_data_version); + pex_msg_send_ext(net, peer, addr); + } if (!peer || !net->net_data_len) return; @@ -628,8 +637,12 @@ network_pex_recv_update_response(struct network *net, const uint8_t *data, size_ return; net_data = pex_msg_update_response_recv(data, len, op, &net_data_len, &version); - if (!net_data) + if (!net_data) { + if (op == PEX_MSG_UPDATE_RESPONSE_REFUSED && net_data_len == -1 && + version > net->net_data_version) + net->update_refused++; return; + } if (version <= net->net_data_version) { free(net_data); @@ -684,6 +697,7 @@ network_pex_recv(struct network *net, struct network_peer *peer, struct pex_hdr case PEX_MSG_UPDATE_RESPONSE: case PEX_MSG_UPDATE_RESPONSE_DATA: case PEX_MSG_UPDATE_RESPONSE_NO_DATA: + case PEX_MSG_UPDATE_RESPONSE_REFUSED: network_pex_recv_update_response(net, data, hdr->len, NULL, hdr->opcode); break; @@ -1063,6 +1077,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr) fallthrough; case PEX_MSG_UPDATE_RESPONSE_DATA: case PEX_MSG_UPDATE_RESPONSE_NO_DATA: + case PEX_MSG_UPDATE_RESPONSE_REFUSED: network_pex_recv_update_response(net, data, hdr->len, addr, hdr->opcode); break; case PEX_MSG_ENDPOINT_PORT_NOTIFY: diff --git a/ubus.c b/ubus.c index 47fa743..d1852b5 100644 --- a/ubus.c +++ b/ubus.c @@ -71,8 +71,13 @@ __network_dump(struct blob_buf *buf, struct network *net) str = blobmsg_alloc_string_buffer(buf, "local_address", INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &local->peer.local_addr.in6, str, INET6_ADDRSTRLEN); blobmsg_add_string_buffer(buf); + } else { + if (net->net_data_len) + blobmsg_add_u8(buf, "no_local_host", true); } + if (net->update_refused) + blobmsg_add_u32(buf, "update_refused", net->update_refused); c = blobmsg_open_table(buf, "peers"); vlist_for_each_element(&net->peers, peer, node) { -- 2.30.2